#include<iostream>
#include<cstdio>
#define N 1000000
using namespace std;
const int inf=(int)(1e9);
int read()
{
	char c=0;
	int sum=0;
	while (c<'0'||c>'9') c=getchar();
	while ('0'<=c&&c<='9') sum=sum*10+c-'0',c=getchar();
	return sum;
}
int n,q,ans,s[N+1];
char c[N+1];
struct reads
{
	int minn,maxn,ans;
};
reads operator + (reads a,reads b)
{
	return (reads){min(a.minn,b.minn),max(a.maxn,b.maxn),max(max(a.ans,b.ans),b.maxn-a.minn)};
}
struct seg
{
	struct node
	{
		int l,r;
		reads data;
	};
	node tree[(N<<2)+1];
	void push_up(int k)
	{
		tree[k].data=tree[k<<1].data+tree[k<<1|1].data;
		return;
	}
	void build(int k,int l,int r)
	{
		tree[k].l=l,tree[k].r=r;
		if (l==r)
		{
			tree[k].data=(reads){s[l],s[l],0};
			return;
		}
		int mid=(l+r)>>1;
		build(k<<1,l,mid),build(k<<1|1,mid+1,r),push_up(k);
		return;
	}
	reads query(int k,int l,int r)
	{
		if (tree[k].l==l&&tree[k].r==r) return tree[k].data;
		int mid=(tree[k].l+tree[k].r)>>1;
		if (r<=mid) return query(k<<1,l,r);
		else if (l>=mid+1) return query(k<<1|1,l,r);
		else return query(k<<1,l,mid)+query(k<<1|1,mid+1,r);
	}
};
seg T;
int main()
{
	freopen("good.in","r",stdin);
	freopen("good.out","w",stdout);
	int l,r;
	n=read(),q=read();
	for (int i=1;i<=n;++i) cin>>c[i],s[i]=s[i-1]+((c[i]=='1')?1:-1);
	T.build(1,0,n);
	while (q--)
	{
		l=read(),r=read();
		if (s[r]-s[l-1]==-(r-l+1)) ans^=(r-l+2);
		else ans^=(T.query(1,l-1,r).ans-(s[r]-s[l-1]));
	}
	printf("%d\n",ans);
	return 0;
}
